package com.andova.glcamera.texture

import android.content.Context
import android.util.AttributeSet
import androidx.annotation.FloatRange
import com.andova.egl.HT
import com.andova.egl.OnTextureBridger
import com.andova.egl.OnTextureListener
import com.andova.glcamera.DEFAULT_COLOR_FORMAT
import com.andova.glcamera.GlFrameHThread
import com.andova.glcamera.device.CameraBuilder
import com.andova.glcamera.device.CameraCallback
import com.andova.glcamera.pool.HdrThreadFactory
import com.andova.gltexture.GLTextureView

abstract class CameraTextureView(context: Context, attrs: AttributeSet?) : GLTextureView(context, attrs) {
    private var mHThread: GlFrameHThread? = null
    private var mBridger: OnTextureBridger? = null
    private var mListener: OnTextureListener? = null

    /**
     * 该方法最好率先调用
     */
    internal fun useBufferRender(callback: BufferFrameCallback?, builder: CameraBuilder = CameraBuilder.build()): CameraTextureView {
        builder.usePreviewCallback(true)
        getCamera().setBuilder(builder)
        BufferRender(context.applicationContext, callback, getCamera(), getEglHelper()).also {
            mBridger = it
            mListener = it
        }
        return this
    }

    /**
     * 该方法最好率先调用
     */
    internal fun useTextureRender(callback: TextureFrameCallback?, builder: CameraBuilder = CameraBuilder.build()): CameraTextureView {
        getCamera().setBuilder(builder)
        TextureRender(context.applicationContext, callback, getCamera(), getEglHelper()).also {
            mBridger = it
            mListener = it
        }
        return this
    }

    internal fun flipScale(@FloatRange(from = -1.0, to = 1.0) xFlipScale: Float, @FloatRange(from = -1.0, to = 1.0) yFlipScale: Float): CameraTextureView {
        mBridger?.flipScale(xFlipScale, yFlipScale)
        return this
    }

    internal fun rotateRadian(radian: Double): CameraTextureView {
        mBridger?.rotateRadian(radian)
        return this
    }

    internal fun lazyCallback(sleepMillisecond: Long): CameraTextureView {
        mBridger?.lazyCallback(sleepMillisecond)
        return this
    }

    internal fun resume(): CameraTextureView {
        mBridger?.resume()
        return this
    }

    internal fun pause(clearColor: Boolean): CameraTextureView {
        mBridger?.pause(clearColor)
        return this
    }

    internal fun action(command: Int): CameraTextureView {
        mBridger?.action(command)
        return this
    }

    internal fun handler(handler: GlFrameHThread?): CameraTextureView {
        this.mHThread = handler
        mBridger?.handler(handler)
        return this
    }

    internal fun x(@FloatRange(from = 0.1, to = 2.0) x: Float): CameraTextureView {
        mBridger?.x(x)
        return this
    }

    internal fun y(@FloatRange(from = 0.1, to = 2.0) y: Float): CameraTextureView {
        mBridger?.y(y)
        return this
    }

    internal fun start(delayMillis: Long = 0L, format: Int = DEFAULT_COLOR_FORMAT) {
        mBridger?.start(delayMillis, format)
        surfaceTextureListener = this
    }

    internal fun stop() {
        mHThread = null
    }

    override fun onTaskHT(): HT {
        val id = getCamera().getCameraId().toString()
        return HdrThreadFactory.get().borrowTask(id)
    }

    override fun onTextureHT(): HT {
        val id = getCamera().getCameraId().toString()
        return HdrThreadFactory.get().borrowTexture(id)
    }

    override fun onTextureListener(): OnTextureListener {
        return mListener ?: throw NullPointerException("you should call useTextureRender or useBufferRender method first!")
    }

    /**
     * 确保这个函数返回的是一个单例
     */
    abstract fun getCamera(): CameraCallback
}